﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using GraphosData;

namespace GraphosControls
{
    class SearchEngine
    {
        private const int PARTIAL_MATCH_THRESH = 3;

        private IList<Node> data;
        private Node partialMatch = null;

        public Node PartialMatch
        {
            get { return partialMatch; }
        }
    
        public SearchEngine(IList<Node> data)
        {
            this.data = data;
        }

        public List<Node> Search(String strFind)
        {
            if (strFind == null)
                throw new NullReferenceException();

            SortedList<String, Node> frontResults = new SortedList<String, Node> ();
            SortedList<String, Node> midResults = new SortedList<String, Node>();
            SortedList<String, Node> backResults = new SortedList<String, Node> ();
            String first, last;
            char[] delims = { ' ' };
            String[] terms = strFind.Split(delims);
            bool inserted;

            foreach(Node n in data)
            {
                first = n.Person.FirstName.ToLower();
                last = n.Person.LastName.ToLower();

                //insert each name only once
                if (frontResults.ContainsKey(first + last) ||
                        midResults.ContainsKey(first + last) ||
                        backResults.ContainsKey(first + last))
                    continue;

                if (terms.Length == 1)
                {
                    if (first.StartsWith(terms[0]))
                        frontResults.Add(first + last, n);
                    else if (last.StartsWith(terms[0]))
                        midResults.Add(first + last, n);
                    else if (Regex.IsMatch(first, terms[0] + ".*"))
                        backResults.Add(first + last, n);
                    else if (Regex.IsMatch(last, terms[0] + ".*"))
                        backResults.Add(first + last, n);
                }

                if (terms.Length == 2)
                {
                    if (first.Equals(terms[0]) && last.StartsWith(terms[1]))
                        frontResults.Add(first + last, n);
                    else if (first.StartsWith(terms[0]) && last.StartsWith(terms[1]))
                        midResults.Add(first + last, n);
                    else if (Regex.IsMatch(first, terms[0] + ".*") && last.StartsWith(terms[1]))
                        backResults.Add(first + last, n);
                    else if (Regex.IsMatch(first, terms[0] + ".*") && Regex.IsMatch(last, ".*" + terms[0] + ".*"))
                        backResults.Add(first + last, n);
                }
            }

            List<Node> results = new List<Node>(frontResults.Values.ToArray<Node>());
            results.AddRange(midResults.Values.ToArray<Node>());
            results.AddRange(backResults.Values.ToArray<Node>());
            return results;
        }
    }
}
